package one.stand.service.impl;

import com.fasterxml.jackson.databind.util.BeanUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import one.stand.advice.ExceptionHandlerAdvice;
import one.stand.enums.CouponStateEnums;
import one.stand.exception.SystemException;
import one.stand.model.CompanyCouponModel;
import one.stand.model.ResultModel;
import one.stand.model.UserCommonModel;
import one.stand.model.UserCouponModel;
import one.stand.request.*;
import one.stand.request.coupon.GoodsCouponQuery;
import one.stand.response.CompanyCouponResponse;
import one.stand.response.UserCouponResponse;
import one.stand.service.UserCouponService;
import one.stand.util.DateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: QIK
 * @CreateDate: 2019/6/24 17:26
 */
@Service
@Transactional
public class UserCouponServiceImpl extends PublicBaseService implements UserCouponService {
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultModel<Boolean> receive(CouponRequest request) {

        CompanyCouponModel outModel = companyCouponMapper.selectByPrimaryKey(request.getCouponId());
        if (null == outModel) {
            log.info("优惠券未获取到数据。。。。。");
            return ResultModel.fail("抱歉，优惠券已经领取完了");
        }
        if (outModel.getGrantEndTime().getTime() < currentDate().getTime()) {
            log.info("当前不在优惠券领取时间范围内。。。。");
            return ResultModel.fail("抱歉，您来晚了一步!");
        }
//        outModel.setSurplusNum(outModel.getSurplusNum() - outModel.getReceiveNum());
        companyCouponMapper.updateByPrimaryKeySelective(outModel);
        log.info("修改优惠券剩余数量。。。。。");
        UserCouponModel inModel = new UserCouponModel();
        inModel.setUserId(request.getId().intValue());
        inModel.setCouponId(request.getCouponId());
        inModel.setNum(outModel.getReceiveNum());
        inModel.setCreateTime(currentDate());
        int insertRes = userCouponMapper.insertSelective(inModel);
        if (insertRes <= 0) {
            return ResultModel.fail("修改优惠券失败");
        }
        return ResultModel.success();
    }

    @Override
    public ResultModel<PageInfo<UserCouponResponse>> myList(UserCouponRequest request) {
        UserCouponModel userCouponModel = new UserCouponModel();
        userCouponModel.setUserId(request.getId().intValue());
        BeanUtils.copyProperties(request,userCouponModel);
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<UserCouponResponse> list = userCouponMapper.selectListByUserId(userCouponModel);
        PageInfo<UserCouponResponse> pageInfo = new PageInfo(list);
        return ResultModel.success(pageInfo);
    }

    /**
     * 查询没有领取的所有公司的 优惠券
     * //todo 应该调整为查询当前用户到访过的公司优惠券或者已经存为相互好友的公司下的优惠券
     * @param request
     * @return
     */
    @Override
    public ResultModel<List<CompanyCouponResponse>> noReceive(UserCouponRequest request) {

        UserCouponModel userCouponModel = new UserCouponModel();
        userCouponModel.setCompanyId(request.getCompanyId());
        userCouponModel.setUserId(request.getId().intValue());
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<CompanyCouponModel> list = userCouponMapper.selectListByCompanyIdAndNotInCouponId(userCouponModel);
        List<CompanyCouponResponse> responseList = new ArrayList<>();
        list.forEach(l -> {
            {
                CompanyCouponResponse response = new CompanyCouponResponse();
                BeanUtils.copyProperties(l, response);
                responseList.add(response);
            }
        });
        PageInfo<CompanyCouponResponse> pageInfo = new PageInfo(responseList);
        return ResultModel.success(pageInfo);
    }

    /**
     * 发放优惠券
     * @param requestGrant
     * @return 返回当前发放的优惠券
     */
    @Override
    public ResultModel<List<UserCouponResponse>> grantCoupon(GrantCouponRequest requestGrant) {
        //todo 检查用户是否已经领取过优惠券
//        grant_mode 发放类型/方式，1：自动发放，2手动领取，3红包发放  grantStartTime grantEndTime
        UserCouponModel userCouponModel = new UserCouponModel();
        // 检查 coupon_num 是否为0 如果为0 则不限制，可以继续发放，如果不是则检查次数
        userCouponModel.setGrantMode(1);
        final Date da = new Date();
        //查询大于当前时间的优惠券
        userCouponModel.setGrantStartTime(da);
        userCouponModel.setCompanyId(requestGrant.getCompanyId().longValue());
        //用户id 排除用户已经领取的优惠券
        userCouponModel.setUserId(requestGrant.getId().intValue());

        List<CompanyCouponModel> companyCouponModels = this.userCouponMapper.selectListByCompanyIdAndNotInCouponId(userCouponModel);
        log.info("优惠券领取列表:{}",companyCouponModels);
        List<UserCouponResponse> couponResponses = new ArrayList<>();
        companyCouponModels.forEach(companyCouponModel -> {
            try {
                UserCouponModel couponModel = grantCoupon(companyCouponModel.getCouponId(),1,requestGrant.getId());
                UserCouponResponse response = new UserCouponResponse();
                BeanUtils.copyProperties(couponModel,response);
                response.setCouponType(companyCouponModel.getCouponType());
                couponResponses.add(response);

            } catch (SystemException e) {
                e.printStackTrace();
            }
        });
        return ResultModel.success(couponResponses);
    }

    /**
     * 领取优惠券
     * @param receiveCouponRequest
     * @return
     */
    @Override
    public ResultModel<Boolean> receiveCoupon(CouponRequest receiveCouponRequest) throws SystemException {

        //检查优惠券是否已经过期
        CompanyCouponModel companyCouponModel = this.companyCouponMapper.selectByPrimaryKey(receiveCouponRequest.getCouponId());
        if(companyCouponModel == null){
            return ResultModel.fail("优惠券未找到");
        }
        if(companyCouponModel.getEffectiveEndTime().getTime() < DateUtil.now().getTime()){
            return ResultModel.fail("优惠券已过期");
        }

        //检查是否已经领取过
        UserCouponModel oldModel = this.userCouponMapper.queryUserCoupon(new UserCouponModel(){{
            setUserId(receiveCouponRequest.getUserId().intValue());
            setCouponId(receiveCouponRequest.getCouponId());
        }});
        if(oldModel != null){
            return ResultModel.fail("已经领取过啦");
        }

        if(grantCoupon(receiveCouponRequest.getCouponId(),2,receiveCouponRequest.getId()) != null){
            return ResultModel.success();
        }
        return ResultModel.fail("优惠券已经被抢光啦");
    }


    /**
     * 用户登录默认发放优惠券
     * @param couponId
     * @param grantMode
     * @return
     */
    public UserCouponModel grantCoupon(final Long couponId,final Integer grantMode,final Long userId) throws SystemException {
        CompanyCouponModel companyCouponModel = this.companyCouponMapper.selectByPrimaryKey(couponId);
        if(companyCouponModel == null){
            throw new SystemException("未找到优惠券");
        }

        UserCouponModel userCommonModel = new UserCouponModel();
        BeanUtils.copyProperties(companyCouponModel,userCommonModel,"id");
        userCommonModel.setUserId(userId.intValue());
        userCommonModel.setCouponState(CouponStateEnums.TO_USED.getCode());
        //发放类型，1：自动发放，2手动领取，3红包发放
        userCommonModel.setGrantMode(grantMode);

        userCommonModel.setCreateTime(DateUtil.now());
        userCommonModel.setReceiveTime(DateUtil.now());
        //默认领取1张
        userCommonModel.setNum(1);
        if(this.userCouponMapper.insertSelective(userCommonModel) > 0 ){
            log.info("优惠券领取成功:{}",userCommonModel);
            //更新优惠券领取数量
            companyCouponModel.setReceiveNum(companyCouponModel.getReceiveNum() + 1);
            this.companyCouponMapper.updateByPrimaryKeySelective(companyCouponModel);
            return userCommonModel;
        }
        log.info("优惠券领取失败:{]",userCommonModel);
        return null;
    }


    /**
     *  更新优惠券单号
     * @param couponOrderRequest
     * @return
     */
    @Override
    public ResultModel<UserCouponResponse> updateOrderNum(final CouponOrderRequest couponOrderRequest){
        UserCouponModel userCouponModel = this.userCouponMapper.selectByPrimaryKey(couponOrderRequest.getUserCouponId());
        if(userCouponModel == null){
            //todo throw exception
            return ResultModel.fail();
        }
        userCouponModel.setOrderNum(couponOrderRequest.getOrderNum());
        if(this.userCouponMapper.updateOrderNum(userCouponModel) > 0 ){
            return ResultModel.success();
        }
        return ResultModel.fail();
    }

    /**
     *
     * @param goodsCouponQuery
     * @return
     */
    @Override
    public ResultModel<List<UserCouponResponse>> selectUserCouponNotUsed(GoodsCouponQuery goodsCouponQuery) {
        UserCouponModel userCouponModel = new UserCouponModel();
        BeanUtils.copyProperties(goodsCouponQuery,userCouponModel);
        List<CompanyCouponModel> companyCouponModels = this.userCouponMapper.selectUserCouponNotUsed(userCouponModel);
        List<UserCouponResponse> couponResponses = new ArrayList<>();
        companyCouponModels.forEach(companyCouponModel -> {
            UserCouponResponse response =  new UserCouponResponse();
            BeanUtils.copyProperties(companyCouponModel,response);
            couponResponses.add(response);
        });
        return ResultModel.success(couponResponses);

    }
}
